﻿namespace Sai.Cecil
{
	using System;
	using Sai.Core;
	using Sai.Core.Introspection;
	using Mono.Cecil;

	/// <summary>
	/// Mono Cecil specific implementation of assembly reflection.
	/// </summary>
	public class MonoCecilAssemblyIntrospector : IAssemblyIntrospector
	{
		/// <summary>
		/// Examines assembly reflection info and creates an AssemblyIntrospection object.
		/// </summary>
		/// <param name="assembly">The assembly.</param>
		/// <returns>The introspected object.</returns>
		public IntrospectedAssembly IntrospectAssembly(ProductAssembly assembly)
		{
			if (assembly == null)
			{
				throw new ArgumentNullException("assembly");
			}

			var assemblyContent = AssemblyDefinition.ReadAssembly(assembly.Path);

			var introspection = new IntrospectedAssembly(assembly.Name, assemblyContent.Name.Version);

            introspection.RuntimeVersion = assemblyContent.MainModule.Runtime.ToString();

			foreach (var discovered in assemblyContent.MainModule.Types)
			{
				discovered.AddTo(introspection);
			}

            foreach(var reference in assemblyContent.MainModule.AssemblyReferences)
            {
                reference.AddTo(introspection); 
            }

			return introspection;
		}
	}
}
